﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using WebApiCoreJWTDemo.Api.Filters;
using WebApiCoreJWTDemo.Common;
using WebApiCoreJWTDemo.Model;
using DateTimeUtil = WebApiCoreJWTDemo.Common.DateTimeUtil;

namespace WebApiCoreJWTDemo.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [Route("GetToken")]
        [HttpGet]
        public IActionResult GetToken(string data)
        {
            LoginViewModel model = JsonConvert.DeserializeObject<LoginViewModel>(data);
            model.Id = "1";
            model.Phone = "138000000";
            model.Password = "e10adc3949ba59abbe56e057f20f883e";
            ResponseResult responseResult = new ResponseResult();
            responseResult.Success = true;
            responseResult.Data = JWTUtil.GetToken(model);
            return Ok(responseResult);
        }

        [Route("GetUserInfo")]
        [HttpGet]
        [CheckJWTFilter]
        public IActionResult GetUserInfo()
        {
            //获取当前请求用户的信息，包含token信息
            var claimIdentity = (ClaimsIdentity)HttpContext.User.Identity;
            string name = claimIdentity.FindFirst(JwtClaimTypes.Name).Value;
            string phoneNumber = claimIdentity.FindFirst(JwtClaimTypes.PhoneNumber).Value;
            string expirationTimeStamp = claimIdentity.FindFirst(JwtClaimTypes.Expiration).Value;
            DateTime expiration = DateTimeUtil.Unix2Datetime(Convert.ToInt64(expirationTimeStamp));
            int code = GetStatusCode(expiration, Appsettings.TokenCacheMinutes);
            return new JsonResult(new ResponseResult() { Success = true, Data = name + "用户资料", Code = code });
        }

        [CheckJWTFilter]
        [HttpGet]
        [Route("RefreshToken")]
        public IActionResult RefreshToken()
        {
            string token = HttpContext.Request.Headers["Authorization"].ToString();
            string[] tokenArray = token.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            var claimIdentity = (ClaimsIdentity)HttpContext.User.Identity;
            string expirationTimeStamp = claimIdentity.FindFirst(JwtClaimTypes.Expiration)?.Value;
            if (string.IsNullOrEmpty(expirationTimeStamp))
            {
                return new JsonResult(new ResponseResult() { Success = false, Data = tokenArray.Length > 1 ? tokenArray[1] : tokenArray[0] });
            }
            DateTime expiration = DateTimeUtil.Unix2Datetime(Convert.ToInt64(expirationTimeStamp));
            if (DateTime.Now > expiration && DateTime.Now <= expiration.AddMinutes(Appsettings.TokenCacheMinutes))
            {
                ResponseResult responseResult = new ResponseResult();
                responseResult.Success = true;
                responseResult.Data = JWTUtil.GetToken(claimIdentity);
                return Ok(responseResult);
            }
            return new JsonResult(new ResponseResult() { Success = true, Data = tokenArray.Length > 1 ? tokenArray[1] : tokenArray[0], Code = 200 });
        }

        private int GetStatusCode(DateTime expiration, int tokenCacheMinutes)
        {
            if (expiration < DateTime.Now)
            {
                if (expiration.AddMinutes(tokenCacheMinutes) < DateTime.Now)
                {
                    //token已失效+不在缓冲期内
                    return 9002;
                }
                else
                {
                    //token已失效+在缓冲期内
                    return 9001;
                }
            }
            return 200;
        }
    }
}
